/*
  "Hello World" s využitím MPI
 */
 #include <mpi.h>
 #include <stdio.h>
 #include <string.h>
 #include<unistd.h>

 #include <sstream>

 #define BUFSIZE 512
 #define TAG 0

#include<string>
#include <iostream>
#include <fstream>

std::string readInputFilename(){
    std::string s;
    std::cin >> s;
    return s;
}

bool readFile( const std::string & filename, int * result ){
    std::ifstream f(filename.c_str(),std::ios::in);
    if ( f.is_open() ){
        f >> *result;
        if (f.good() )
            return true;
    }
    return false;
}

std::string getId(int myid){
    char Name[150];
    memset(Name, 0, 150);
    gethostname(Name, 150);
    std::ostringstream oss;
    oss  << myid << "@" << Name;
    return oss.str();
}


 int main(int argc, char *argv[])
 {
   char buff[BUFSIZE];
   int numprocs;
   int myid;

   std::string filename;
   int myNumber = 0;

   MPI_Status stat;

   MPI_Init(&argc,&argv); /* inicializace MPI */
   MPI_Comm_size(MPI_COMM_WORLD,&numprocs); /* zjistíme, kolik procesů běží */
   MPI_Comm_rank(MPI_COMM_WORLD,&myid); /* zjistíme id svého procesu */


   if(myid == 0)
   {

     filename = readInputFilename();

     sprintf(buff, "%s", filename.c_str() );

     for(int i=1;i<numprocs;i++)
     {
       MPI_Send(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
     }

     int ok = readFile(filename,&myNumber) ? 1 : 0;

     for(int i=1;i<numprocs;i++)
     {
       MPI_Recv(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD, &stat);
       std::istringstream iss(buff);
       int okR, number;
       iss >> okR;
       ok = ok && okR;
       if ( ok ){
           iss >> number;
           myNumber += number;
       }
     }
     if (ok){
        std::cout << myNumber << std::endl;
     }else{
         std::cout << "failed to get result" << std::endl;
     }
   }
   else
   {
     /* obdržíme zprávu od procesu s rankem 0: */
     MPI_Recv(buff, BUFSIZE, MPI_CHAR, 0, TAG, MPI_COMM_WORLD, &stat);

     filename = std::string(buff);
     int ok = readFile(filename,&myNumber) ? 1 : 0;

     sprintf(buff, "%d %d : ", ok, myNumber);

     /* Odpovíme na zprávu: */
     MPI_Send(buff, BUFSIZE, MPI_CHAR, 0, TAG, MPI_COMM_WORLD);
   }

   MPI_Finalize();
   return 0;
 }
